﻿using System;
using System.Configuration;

namespace SQDebugging
{
    public class Debugging
    {
        #region Static
        static private string _debugOutputPath = string.Empty;
        static private Debugging _debugging;
        private const string _logfileName = "log.txt";

        /// <summary>
        /// Der Pfad in dem die Logfile abgelegt werden soll, kann programmweit gesetzt werden.
        /// Bei einem Leeren String, wird versucht das Logfile im Programmverzeichnis abzulegen
        /// </summary>
        static public string DebugOutputPath
        {
            get { return _debugOutputPath; }
            set { _debugOutputPath = value; }
        }

        /// <summary>
        /// Lädt den Debugpfad aus der App.Config, wenn keiner hinterlegt wurde wird das lokale Programmverzeichnis genommen.
        /// </summary>
        static public void LoadDebugPathFromAppConfig()
        {
            AppSettingsReader app = new AppSettingsReader();

            try
            {
                DebugOutputPath = (string)app.GetValue("Debugausgabe", typeof(string));
            }
            catch (Exception)
            {
                DebugOutputPath = null;   
            }
            

            //Wenn kein Pfad gefunden werden konnte oder der String 0 Zeichen lang ist, dann das Tempverzeichnis wählen um die Logginginfos auszugeben
            if (DebugOutputPath == null || DebugOutputPath.Trim().Length == 0)
            {
                DebugOutputPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), _logfileName);
            }
        }

        /// <summary>
        /// Schreiben der Exception in die Ausgabe
        /// </summary>
        /// <param name="exP">Die Exception die in das Logfile geschrieben werden soll.</param>
        public static void WriteLog(Exception exP)
        {
            //Wenn Debugging noch nicht initialisiert wurde, dies initialisieren
            if (_debugging == null)
            {
                _debugging = new Debugging();
            }

            _debugging.DebugWriteLog(exP);
        }

        /// <summary>
        /// Schreiben der Nachricht in die Ausgabe
        /// </summary>
        /// <param name="nachrichtP">Die Nachricht die in das Logfile geschrieben werden soll.</param>
        public static void WriteLog(string nachrichtP)
        {
            //Wenn Debugging noch nicht initialisiert wurde, dies initialisieren
            if (_debugging == null)
            {
                _debugging = new Debugging();
            }

            _debugging.DebugWriteLog(nachrichtP);
        }

        /// <summary>
        /// Schreiben der Nachticht und Exception in die Ausgabedatei
        /// </summary>
        /// <param name="message">Nachricht die ausgegeben werden soll</param>
        /// <param name="exception">exception die ausgegeben werden soll</param>
        public static void WriteLog(string message, Exception exception)
        {
            WriteLog(message);
            WriteLog(exception);
        }

        /// <summary>
        /// Gibt zur übergebenen Expception den kompletten Stacktrace zurück
        /// </summary>
        public static string GetStackTrace(Exception exP)
        {
            //Den kompletten Stacktrace durchlaufen
            string errText = string.Empty;
            while (exP != null)
            {
                errText += exP.ToString() + "\n\n";
                exP = exP.InnerException;
            }

            return errText;
        }

        #endregion

        #region Konstruktor
        public Debugging()
        {

        }
        #endregion

        #region Functions/Subs
        /// <summary>
        /// Schreiben der Expeption in die Ausgabe
        /// </summary>
        /// <param name="exP">Die Exception die in das Logfile geschrieben werden soll</param>
        public void DebugWriteLog(Exception exP)
        {
            try
            {
                SetOutputPath();
                //Den kompletten Stacktrace durchlaufen und ausgeben
                System.IO.File.AppendAllText(DebugOutputPath, string.Format("\n{0}: {1}\n\n", DateTime.Now.ToString("dd.MM.yyyy hh:mm"), GetStackTrace(exP)));
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// Schreiben der Nachricht in die Ausgabe
        /// </summary>
        /// <param name="nachrichtP">Die Nachricht die in das Logfile geschrieben werden soll.</param>
        public void DebugWriteLog(string nachrichtP)
        {
            try
            {
                SetOutputPath();
                System.IO.File.AppendAllText(DebugOutputPath, "\n" + DateTime.Now.ToString("dd.MM.yyyy hh:mm") + ": " + nachrichtP + "\n\n");
            }
            catch (Exception ex)
            {
                Debugging.WriteLog(ex);
            }
        }

        /// <summary>
        /// Prüft ob ein Ausgabepfad angegeben wurde und wenn nicht wird hier erst einmal das Programmverzeichnis genommen.
        /// und vorher wird versucht noch den Pfad aus der AppConfig auszulesen
        /// </summary>
        private void SetOutputPath()
        {
            if (DebugOutputPath == null || DebugOutputPath.Trim().Length == 0)
            {
                LoadDebugPathFromAppConfig();
            }
        }
        #endregion


    }
}
